"""Python GTK based File Browser"""
"""http://docs.python.org/lib/module-xmlrpclib.html"""
import gtk
import xmlrpclib
import sys


class FileSaveDialog:
	"""This class creates a file save dialog and handles the associated widget events.It also saves the file to disk."""
	def __init__(self, actualpath,server):
		self.actualpath = actualpath
		self.server = server
		self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
		self.window.set_title("Enter the File Name")
		self.window.connect('delete_event', self.delete_event)
		self.vbox = gtk.VBox(False, 0)
		self.hbox1 = gtk.HBox(False, 0)
		self.hbox2 = gtk.HBox(False, 0)
		self.textentry = gtk.Entry();
		self.label = gtk.Label("Enter the Location to save")
		self.hbox1.pack_start(self.label)
		self.hbox1.pack_start(self.textentry)
		self.okbutton = gtk.Button("Ok")
		self.okbutton.connect ("clicked", self.on_ok_clicked)
		self.cancelbutton = gtk.Button("Cancel")
		self.cancelbutton.connect ("clicked", self.on_cancel_clicked)
		self.hbox2.pack_start(self.okbutton)
		self.hbox2.pack_start(self.cancelbutton)
		self.vbox.pack_start(self.hbox1)
		self.vbox.pack_start(self.hbox2)
		self.window.add(self.vbox)
		self.window.show_all()
	
	def on_ok_clicked(self, widget):
		print 'Message Box Ok clicked'
		if self.textentry.get_text()=="":
			return False
		x = self.server.FileServer.get(self.actualpath)
		newfile = open(self.textentry.get_text(),"w")
		try:
			for y in x:
				#print y
				newfile.write(str(y))
			print "File Write Ok"
		except:
			print "Write failed"
		newfile.close()
		gtk.main_quit()
		response = self.window.destroy()
		return False
	
	def on_cancel_clicked(self, widget):
		print "Cancel Button clicked"
		gtk.main_quit()
		self.window.destroy()
		return False

	def delete_event(self, widget, event, data=None):
		return True

class MainWindow:

	
	
	def create_window(self):
		"""Creates a File Browser Window"""
		self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
		self.window.connect('delete_event', self.delete_event)
		self.box = gtk.VBox(False, 0)
		self.scrollwindow = gtk.ScrolledWindow()
		self.scrollwindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
		self.scrollwindow.set_size_request(200,200)
		self.listdata = gtk.ListStore(str, str, str)
		self.listview = gtk.TreeView(self.listdata)
		self.listcell = gtk.CellRendererText()
		self.listcolumn = gtk.TreeViewColumn('Name', self.listcell, text=0)
		self.listcolumn.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
		self.listcolumn.set_sort_column_id(0)
		self.listview.append_column(self.listcolumn)
		self.listview.set_search_column(0)
		self.listview.set_reorderable(True)		
		self.listcolumn1 = gtk.TreeViewColumn("Path", self.listcell, text=1)
		self.listcolumn1.set_visible(False)
		self.listcolumn1.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
		self.listview.append_column(self.listcolumn1)
		self.listcolumn2 = gtk.TreeViewColumn("Type", self.listcell, text=2)
		self.listcolumn2.set_visible(True)
		self.listcolumn2.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
		self.listview.append_column(self.listcolumn2)
		self.createmenu()
		self.box.pack_start(self.menubar, False)
		self.scrollwindow.add(self.listview)
		self.box.pack_start(self.scrollwindow)
		self.window.add(self.box)
		self.window.show_all()
		self.listview.connect_object("row-activated",self.row_activated,None)
		
		
		
	def createmenu(self):
		"""Creates the menu inside the File Browser Window"""
		self.menubar = gtk.MenuBar()
		#file menu
		self.filemenu = gtk.Menu()
		self.registeritem = gtk.MenuItem("Register")
		self.saveitem = gtk.MenuItem("Save")
		self.quititem = gtk.MenuItem("Quit")
		self.registeritem.connect_object("activate", self.registeritem_activate,\
					None)
		self.saveitem.connect_object("activate", self.saveitem_activate, None)
		self.quititem.connect_object ("activate", self.quititem_activate, self.window)
		self.filemenu.append(self.registeritem)
		self.filemenu.append(self.saveitem)
		self.filemenu.append(self.quititem)
		self.fileitem = gtk.MenuItem("File")
		self.fileitem.set_submenu(self.filemenu)
		self.menubar.append(self.fileitem)
		
		#Go menu
		self.gomenu = gtk.Menu()
		self.homeitem = gtk.MenuItem("Home")
		self.homeitem.connect_object("activate", self.homeitem_activate, None)
		self.backitem = gtk.MenuItem("Back")
		self.backitem.connect_object("activate", self.backitem_activate, None)
		self.gomenu.append(self.homeitem)
		self.gomenu.append(self.backitem)
		self.goitem = gtk.MenuItem("Go")
		self.goitem.set_submenu(self.gomenu)
		self.menubar.append(self.goitem)
	
		

	def registeritem_activate(self, widget, data=None):
		if self.register() == True :
			self.populate_view(self.initialList)
			#print self.initialList

	def saveitem_activate(self, widget, data=None):
		sel = self.listview.get_selection()
		if sel != None:
			model, iter = sel.get_selected()
			canonical_name = model.get_value(iter, 0)
			actual_path = model.get_value(iter, 1)
			mime_type = model.get_value(iter, 2)
			#print sel, model, iter, canonical_name, actual_path
			if mime_type == "file/bytes":
				self.get_file(actual_path)
		
		
	def delete_event(self, widget, event, data=None):
		gtk.main_quit()
		return False
		
	def quititem_activate(self, widget, data=None):
		gtk.main_quit()
		return False

	def row_activated(self, widget, row, data=None):
		"""Handles the activate row event in Tree Widget\n
		Input:row which is double clicked\n
		Ouput:File Save dialog if it is a file or directory contents in case of a directory"""
		#print "Row Activated ", widget, row
		sel = self.listview.get_selection()
		model, iter = sel.get_selected()
		canonical_name = model.get_value(iter, 0)
		actual_path = model.get_value(iter, 1)
		mime_type = model.get_value(iter, 2)
		#print sel, model, iter, canonical_name, actual_path
		if mime_type == "file/directory":
			self.get_dir_contents(actual_path)
		elif mime_type == "file/bytes":
			self.get_file(actual_path)
			
		else:
			self.get_dir_contents(actual_path)
			
	def get_dir_contents(self, val):
		"""Gets the directory contents of "a double clicked  row" in Tree Widget by executing a rpc call to the server\n
		Input:The Directory name
		Side Effect:The directory listing from the server,Population of Tree Widget"""
		try:
			self.returned_list = self.server.FileServer.list(val)
			#print self.returned_list
			self.curlist = self.returned_list
			self.back = self.curlist[0]
			#print "BACK",self.back
			self.populate_view(self.returned_list)
		except:
			print "error occured"

		
	def homeitem_activate(self, widget, data=None):
		"""Initializes the Tree Widget with the contents of HNFS Home directory"""
		if self.register() == True :
			self.populate_view(self.initialList)
			#print self.initialList

	def backitem_activate(self, widget, data=None):
		if self.back != None:
			#print self.back[0]
			self.get_dir_contents(self.back[0])
			
	def populate_view(self,data):
		"""Populates ListStore ( indirectly List ) with the given data\n
		Input:data for the List Store
		SideEffect: Updated List Widget"""
		
		gtk.ListStore.clear(self.listdata)
		for y,z,x in data:
			#print z,x
			self.listdata.append([z,y,x])
	
	def register(self):
		#print "In register 1"
		"""Registers to the Local Server\n
		Input:Server port
		Output:None"""
		try:
			self.server_url = 'http://127.0.0.1:'+str(self.port);
			#print self.server_url
			self.server = xmlrpclib.Server(self.server_url);	
			#print self.server
			self.initialList = self.server.FileServer.register()
			#print self.server
			self.curlist = self.initialList
			return True
		except:
			print "error in server access...check your connection"
		return False
			
	def get_file(self, actual_path):
		"""Handler for fetching a file from the GFS\n
			Input  : Path of the file in GFS\n
			Output : Dialog box for saving the file to the user specified path"""
		window = FileSaveDialog(actual_path,self.server)
		gtk.main()
		pass
	
	def main(self):
		gtk.main()
	
	def __init__(self,port):
		self.port = port
		self.create_window()
		if self.register() == True :
			self.populate_view(self.initialList)
			#print self.initialList
		

if __name__ == "__main__":
	
	if len(sys.argv) == 1:
		print "Usage: ./pygtk_gui.py #port_no"
		sys.exit(1)
	window = MainWindow(sys.argv[1])
	window.main()
